package queue;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @ClassName MyBlockingQueue
 * @Description 手动实现阻塞队列
 * @Company inspur
 * @Author Kevin
 * @Date 2020/7/10 17:02
 * @Version 1.0
 */
public class MyBlockingQueue<T> {
    private MyQueue<T> queue;
    private final ReentrantLock myLock = new ReentrantLock();
    private final Condition notFull = myLock.newCondition();
    private final Condition notEmpty = myLock.newCondition();
    private final int length;

    public MyBlockingQueue(int length) {
        this.length = length;
    }

    public void put(T t) {
        myLock.lock();
        if (queue == null) {
            queue = new MyQueue<>(t);
            myLock.unlock();
            return;
        }
        try {
            while (!queue.put(t, length)) {
                notFull.await();
            }
            notEmpty.signalAll();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            myLock.unlock();
        }
    }

    public T take(){
        myLock.lock();
        T t = null;
        try {
            while (queue == null || (t = queue.get()) == null) {
                notEmpty.await();
            }
            notFull.signalAll();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            myLock.unlock();
        }
        return t;
    }
}
